﻿using System;
using System.Collections.Generic;
using System.Text;

namespace RaisingStudio.Data.Common
{
    /// <summary>
    /// Database operation class.
    /// </summary>
    public class Database
    {
        /// <summary>
        /// Execute SQL command.
        /// </summary>
        /// <param name="command">Command.</param>
        /// <returns>The number of rows affected.</returns>
        public static int ExecuteNonQueryCommand(System.Data.IDbCommand command)
        {
            System.Data.ConnectionState previousConnectionState = command.Connection.State;
            if ((command.Connection.State & System.Data.ConnectionState.Open) != System.Data.ConnectionState.Open)
            {
                command.Connection.Open();
            }
            try
            {
                int returnValue = command.ExecuteNonQuery();
                return returnValue;
            }
            finally
            {
                if ((previousConnectionState == System.Data.ConnectionState.Closed))
                {
                    command.Connection.Close();
                }
            }
        }

        /// <summary>
        /// Executes the query, and returns the first column of the first row in the result set returned by the query. Additional columns or rows are ignored.
        /// </summary>
        /// <param name="command">Command.</param>
        /// <returns>The first column of the first row in the result set, or a null reference (Nothing in Visual Basic) if the result set is empty.</returns>
        public static object ExecuteScalarCommand(System.Data.IDbCommand command)
        {
            System.Data.ConnectionState previousConnectionState = command.Connection.State;
            if ((command.Connection.State & System.Data.ConnectionState.Open) != System.Data.ConnectionState.Open)
            {
                command.Connection.Open();
            }
            try
            {
                object returnValue = command.ExecuteScalar();
                return returnValue;
            }
            finally
            {
                if ((previousConnectionState == System.Data.ConnectionState.Closed))
                {
                    command.Connection.Close();
                }
            }
        }

        /// <summary>
        /// Execute the Command to the Connection and builds a DbDataReader.
        /// </summary>
        /// <param name="command">Command.</param>
        /// <returns>A DbDataReader object.</returns>
        public static System.Data.IDataReader ExecuteReaderCommand(System.Data.IDbCommand command)
        {
            System.Data.ConnectionState previousConnectionState = command.Connection.State;
            if ((command.Connection.State & System.Data.ConnectionState.Open) != System.Data.ConnectionState.Open)
            {
                command.Connection.Open();
            }
            try
            {
                if ((previousConnectionState == System.Data.ConnectionState.Closed))
                {
                    System.Data.IDataReader returnValue = command.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
                    return returnValue;
                }
                else
                {
                    System.Data.IDataReader returnValue = command.ExecuteReader();
                    return returnValue;
                }
            }
            catch
            {
                if ((previousConnectionState == System.Data.ConnectionState.Closed))
                {
                    command.Connection.Close();
                }
                throw;
            }
        }

        /// <summary>
        /// Execute SQL command.
        /// </summary>
        /// <param name="command">Command.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>The number of rows affected.</returns>
        public static int ExecuteNonQueryCommand(System.Data.IDbCommand command, System.Data.IDbTransaction transaction)
        {
            System.Data.ConnectionState previousConnectionState = command.Connection.State;
            if ((command.Connection.State & System.Data.ConnectionState.Open) != System.Data.ConnectionState.Open)
            {
                command.Connection.Open();
            }
            try
            {
                // TODO: 好像还是有问题。
                if (transaction != null)
                {
                    command.Transaction = transaction;
                }
                int returnValue = command.ExecuteNonQuery();
                return returnValue;
            }
            finally
            {
                if ((previousConnectionState == System.Data.ConnectionState.Closed))
                {
                    command.Connection.Close();
                }
            }
        }

        /// <summary>
        /// Executes the query, and returns the first column of the first row in the result set returned by the query. Additional columns or rows are ignored.
        /// </summary>
        /// <param name="command">Command.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>The first column of the first row in the result set, or a null reference (Nothing in Visual Basic) if the result set is empty.</returns>
        public static object ExecuteScalarCommand(System.Data.IDbCommand command, System.Data.IDbTransaction transaction)
        {
            System.Data.ConnectionState previousConnectionState = command.Connection.State;
            if ((command.Connection.State & System.Data.ConnectionState.Open) != System.Data.ConnectionState.Open)
            {
                command.Connection.Open();
            }
            try
            {
                // TODO: 好像还是有问题。
                if (transaction != null)
                {
                    command.Transaction = transaction;
                }
                object returnValue = command.ExecuteScalar();
                return returnValue;
            }
            finally
            {
                if ((previousConnectionState == System.Data.ConnectionState.Closed))
                {
                    command.Connection.Close();
                }
            }
        }

        /// <summary>
        /// Execute the Command to the Connection and builds a DbDataReader.
        /// </summary>
        /// <param name="command">Command.</param>
        /// <param name="transaction">Database transaction.</param>
        /// <returns>A DbDataReader object.</returns>
        public static System.Data.IDataReader ExecuteReaderCommand(System.Data.IDbCommand command, System.Data.IDbTransaction transaction)
        {
            System.Data.ConnectionState previousConnectionState = command.Connection.State;
            if ((command.Connection.State & System.Data.ConnectionState.Open) != System.Data.ConnectionState.Open)
            {
                command.Connection.Open();
            }
            try
            {
                // TODO: 好像还是有问题。
                if (transaction != null)
                {
                    command.Transaction = transaction;
                }
                if ((previousConnectionState == System.Data.ConnectionState.Closed))
                {
                    System.Data.IDataReader returnValue = command.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
                    return returnValue;
                }
                else
                {
                    System.Data.IDataReader returnValue = command.ExecuteReader();
                    return returnValue;
                }
            }
            catch
            {
                if ((previousConnectionState == System.Data.ConnectionState.Closed))
                {
                    command.Connection.Close();
                }
                throw;
            }
        }
    }
}
